﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Smark.Data.Mappings
{
    [AttributeUsage(AttributeTargets.Property)]
    public abstract class ValueAttribute:Attribute
    {
        public ValueAttribute(bool afterupdate)
        {
            AfterByUpdate = afterupdate;   
        }
        public bool AfterByUpdate
        {
            get;
            set;
        }
        public virtual void Executing(IConnectinContext cc,object data,PropertyMapper pm,string table)
        {
        }
        public virtual void Executed(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class IDENTITY : ValueAttribute
    {
        public IDENTITY()
            : base(true)
        {
        }
        public override void Executed(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            Command cmd = new Command("select @@IDENTITY ");
            object value = cc.ExecuteScalar(cmd);
            pm.Handler.Set(data,Convert.ChangeType( value,pm.Handler.Property.PropertyType));
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class UID:ValueAttribute
    {
        public UID() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            string uid = Guid.NewGuid().ToString("N");
            pm.Handler.Set(data, uid);
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class YearMonth : ValueAttribute
    {
        public YearMonth() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, DateTime.Now.Year.ToString("0000") + DateTime.Now.Month.ToString("00"));
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class Year : ValueAttribute
    {
        public Year() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, DateTime.Now.Year.ToString());
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class Month : ValueAttribute
    {
        public Month() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, DateTime.Now.Month.ToString());
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class Day : ValueAttribute
    {
        public Day() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, DateTime.Now.Day.ToString());
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class NowDate:ValueAttribute
    {
        public NowDate() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, DateTime.Now);
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class DefaultInt : ValueAttribute
    {
        private int mValue = 0;
        public DefaultInt(int value) : base(false) {
            mValue = value;
        }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, mValue);
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class DefaultDecimal : ValueAttribute
    {
        private decimal mValue = 0;
        public DefaultDecimal(string value)
            : base(false)
        {
            mValue = Convert.ToDecimal(value);
        }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data,mValue);
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class DefaultString : ValueAttribute
    { 
        private string mValue = "";
        public DefaultString(string value)
            : base(false)
        {
            mValue = value;
        }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, mValue);
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class DefaultDate:ValueAttribute
    {
        private DateTime mValue = DateTime.MinValue;
        public DefaultDate(string value)
            : base(false)
        {
            mValue =DateTime.Parse(value);
        }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, mValue);
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class Enabled : ValueAttribute
    {
        public Enabled() : base(false) { }
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            pm.Handler.Set(data, true);
        }
    }

    [AttributeUsage(AttributeTargets.Property)]
    public class DefaultEnum : ValueAttribute
    {
        public DefaultEnum() : base(false) { }
        public DefaultEnum(int value): base(false) 
        {
            mValue = value;
            mInputType = InputType.Int;
        }
        public DefaultEnum(string value)
            : base(false)
        {
            mValue = value;
            mInputType = InputType.String;
            
        }
        private InputType mInputType = InputType.None;
        private object mValue;
        public override void Executing(IConnectinContext cc, object data, PropertyMapper pm, string table)
        {
            if (mInputType == InputType.Int)
            {
                pm.Handler.Set(data, Enum.GetValues(pm.Handler.Property.PropertyType).GetValue((int)mValue));
            }
            else if (mInputType == InputType.String)
            {
                Enum.Parse(pm.Handler.Property.PropertyType, mValue.ToString());
            }
            else
            {
                pm.Handler.Set(data, Enum.GetValues(pm.Handler.Property.PropertyType).GetValue(0));
            }
        }
        enum InputType
        { 
            None,
            Int,
            String
        }
    }


}
